package game.groves.hollow;

import java.util.List;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;

public class Player {

	public enum Movement {
		JUMPING, WALKING, DASHING, BLOCKED // players movement status
	}

	private final static int TERMINAL = 20; // terminal velocity
	private final static int GRAVITY = 1; // gravity for the player
	private static final String TAG = Player.class.getSimpleName();

	private Bitmap bitmap; // the actual bitmap
	private int x; // the X coordinate
	private int y; // the Y coordinate
	private int width;
	private int height;
	private boolean touched; // if screen is touched
	private int maxJumpSpeed = -20; // player's jump speed
	private int walkSpeed; // player's walk speed
	private int dashSpeed; // player's dash speed
	private int yVelo;
	private int xVelo;
	private Movement movement;
	private Point startPoint;
	private Point currPoint;
	private Point endPoint;
	private int screenHeight;
	long startTime;
	long endTime;
	private Animation walkingAnimation;
	private Animation blockedAnimation;
	private Animation jumpingAnimation;
	private Animation fallingAnimation;
	private Animation dashingAnimation;
	private Animation attackingAnimation;
	private Animation currentAnimation = null;
	private Paint paint;
	private Rect newRectX;
	private Rect newRectY;
	private Rect blockRect;

	public Player(Animation walkingAnimation, Animation blockedAnimation,
			Animation jumpingAnimation, Animation fallingAnimation,
			Animation dashingAnimation, Animation attackingAnimation, int x,
			int y, int screenHeight) {
		this.walkingAnimation = walkingAnimation;
		this.blockedAnimation = blockedAnimation;
		this.jumpingAnimation = jumpingAnimation;
		this.fallingAnimation = fallingAnimation;
		this.dashingAnimation = dashingAnimation;
		this.attackingAnimation = attackingAnimation;
		this.x = x;
		this.y = y;
		this.screenHeight = screenHeight;

		width = this.walkingAnimation.getWidth();
		height = this.walkingAnimation.getHeight();
		movement = Movement.JUMPING;
		touched = false;
		currentAnimation = this.jumpingAnimation;
		paint = new Paint();
		newRectX = new Rect();
		newRectY = new Rect();
		blockRect = new Rect();


	}

	public Bitmap getBitmap() {
		return bitmap;
	}

	public void setBitmap(Bitmap bitmap) {
		this.bitmap = bitmap;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public boolean isTouched() {
		return touched;
	}

	public void setTouched(boolean touched) {
		this.touched = touched;
	}
	
	private void setState(Movement movement){
		
	}
	
	//Update Methods ---------------------------------------------------------------------------------------------------------


	public void draw(Canvas canvas) {
		currentAnimation.draw(canvas, this.x, this.y);
		
		newRectX.set(x + xVelo, y + ((height/2) - 1), x + 1, y + ((height/2) + 1));
		newRectY.set(x + ((width/2) - 1), y + yVelo, x + ((width / 2) + 1), y
				+ height + yVelo);	
		
		//paint.setStrokeWidth(1);
		paint.setColor(Color.WHITE);
		canvas.drawLine(newRectX.left, newRectX.top, newRectX.right, newRectX.top, paint);
		canvas.drawLine(newRectX.right, newRectX.top, newRectX.right, newRectX.bottom, paint);
		canvas.drawLine(newRectX.right, newRectX.bottom, newRectX.left, newRectX.bottom, paint);
		canvas.drawLine(newRectX.left, newRectX.bottom, newRectX.left, newRectX.top, paint);

		paint.setColor(Color.CYAN);
		canvas.drawLine(newRectY.left, newRectY.top, newRectY.right, newRectY.top, paint);
		canvas.drawLine(newRectY.right, newRectY.top, newRectY.right, newRectY.bottom, paint);
		canvas.drawLine(newRectY.right, newRectY.bottom, newRectY.left, newRectY.bottom, paint);
		canvas.drawLine(newRectY.left, newRectY.bottom, newRectY.left, newRectY.top, paint);	}

	public void update(long gameTime, List<Block> blocks) {
		if (movement == Movement.JUMPING) {
			if (yVelo <= TERMINAL) {
				yVelo += GRAVITY;
			}
		}
		currentAnimation.update(gameTime);
		move(blocks);
	}
//-----------------------------------------------------------------------------------------------------------------------------------

//Handle Touches and Movement ---------------------------------------------------------------------------------------------------------

	private void move(List<Block> blocks) {

		if (yVelo == 0) {
			yVelo = 10;
		}

		newRectX.set(x + xVelo, y + ((height/2) - 1), x + 1, y + ((height/2) + 1));
		newRectY.set(x + ((width/2) - 1), y + yVelo, x + ((width / 2) + 1), y
				+ height + yVelo);
		
		
		for (Block b : blocks) {
			blockRect.set(b.getX(), b.getY(), b.getX() + b.getWidth(),
					b.getY() + b.getHeight());

			if (newRectX.intersect(blockRect)) {
				newRectX.left = blockRect.right;
				if (movement == Movement.WALKING) {
					movement = Movement.BLOCKED;
				}
			}

			if (newRectY.intersect(blockRect)) {
				if (yVelo > 0) {
					movement = Movement.WALKING;
					newRectY.top = blockRect.top - height;
					yVelo = 0;
				} else if (yVelo < 0) {
					newRectY.top = blockRect.bottom;
					yVelo = 0;
				}
			}

		}
		x = newRectX.left;
		y = newRectY.top;
	}
	
	
	public void setStartPoint(Point startPoint) {
		if (!touched) {
			touched = true;
			this.startPoint = startPoint;
			Log.d(TAG,"The start point is now set at " + this.startPoint.toString());

		}
	}

	public void setCurrPoint(Point currPoint){
		this.currPoint = currPoint;
	}
	
	public void setEndPoint(Point endPoint){
		this.endPoint = endPoint;
		Log.d(TAG,"The end point is now set at " + this.endPoint.toString());
		touched = false;
		handleEndPoint();
	}
	
	private void handleEndPoint(){
		double distance = distance(startPoint, endPoint);
		Log.d(TAG,"The distance between the points is " + distance);

		if (startPoint.y > endPoint.y) {
			jump(distance);
		}
	}

	private double distance(Point p1, Point p2){
		return Math.sqrt(Math.pow(p2.x - p1.x,2) + Math.pow(p2.y - p1.y, 2));
	}

	public void jump(double distance) {
		double percentage;
		Log.d(TAG,"Should Jump now");

		if(distance > (screenHeight/2)){
			percentage = 1.0;
		} else {
			percentage = distance / (screenHeight/2);
		}
		if (movement != Movement.JUMPING) {
			yVelo = (int)(maxJumpSpeed * percentage);
			movement = Movement.JUMPING;
			Log.d(TAG,"Just jumped at a speed of " + yVelo);
		}
	}
	
//---------------------------------------------------------------------------------------------------------
}